package com.coding365.rpcprovider.boot;


import com.coding365.rpcprovider.handler.UserServiceHandler;
import com.coding365.rpcprovider.service.UserServiceImpl;
import com.coding365.rpcprovider.zookeeper.ZookeeperUtil;
import com.lagou.entity.JSONSerializer;
import com.lagou.entity.RpcDecoder;
import com.lagou.entity.RpcEncoder;
import com.lagou.entity.RpcRequest;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.net.InetAddress;

@Component
public class ServerBoot implements CommandLineRunner {

    @Autowired
    private UserServiceHandler userServiceHandler;

    @Autowired
    private ZookeeperUtil zookeeperUtil;

    @Value("${netty.port}")
    private Integer port;

    @Override
    public void run(String... args) throws Exception {
        //启动服务器.
        startServer();
    }

    //创建一个方法启动服务器
    public void startServer() throws InterruptedException {
        //1.创建两个线程池对象
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup  workGroup = new NioEventLoopGroup();

        //2.创建服务端的启动引导对象
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        //3.配置启动引导对象
        serverBootstrap.group(bossGroup,workGroup)
                //设置通道为NIO
                .channel(NioServerSocketChannel.class)
                //创建监听channel
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        //获取管道对象
                        ChannelPipeline pipeline = nioSocketChannel.pipeline();
                        //给管道对象pipeLine 设置编码
                        pipeline.addLast( new RpcDecoder(RpcRequest.class, new JSONSerializer()));
                        pipeline.addLast(new RpcEncoder(RpcRequest.class,new JSONSerializer()));
                        //把我们自顶一个ChannelHander添加到通道中
                        pipeline.addLast(userServiceHandler);

                    }
                });

        //4.绑定端口
        serverBootstrap.bind(port).sync();

        //向zookeeper注册IP和端口
        registerIpAndPort();
    }

    private void registerIpAndPort(){
        try {
            InetAddress inetAddress=InetAddress.getLocalHost();
            String ip=inetAddress.getHostAddress();//获得本机Ip
            zookeeperUtil.registryIpAndPort(ip,port);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


}
